home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Games of Daze
/
Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso
/
x2ftp
/
msdos
/
libs
/
tlp4v11c
/
docu
/
vrclk.txt
< prev
Wrap
Text File
|
1994-05-15
|
9KB
|
308 lines
vrclk.obj function summary:
===========================
This list contains UNIX-like summaries for the routines that
are currently contained in vrclkx.obj.
vrclkx.obj is intended for use with the tgdlp4xx.obj ModeX
graphics driver. However this library could also act as a stand
alone module. In order for vrclkx.obj to work the following
hardware items are required:
- IBM compatible PC/XT/AT with 80188 CPU or above
- a VGA card
vrclkc.obj is assembled for the COMPACT memory model. This means
that all calls to procedures must be declared as NEAR while
pointers to data are all FAR.
vrclkl.obj is assembled for the LARGE memory model. In this
model all calls to procedures as well as all pointers to data
are to be declared as FAR.
vrclkx.obj expects all parameters to be passed using C calling
conventions. The C calling mechanism is described in tgdlp4.txt.
byte startvrclk(ubyte fcreset);
initialize new timer interrupt and start frame counting
FUNCTION:
Before using any of the vrclk library functions this routine
must be called. It reprograms the system timer to generate
interrupts synchronized to the vertical retrace of the VGA card
and installs a new interrupt handler which will increment a
frame counter every interrupt. This means you can concentrate
fully on doing your graphics - wasting no unnecassary time on
frame counting to keep a constant screen update rate for e.g.
double-buffering.
The initial value of the frame counter is passed in fcreset. In
a double-buffered environment it is usefull to give the frame
counter the graphics update frame rate when starting the vrclk
system.
Example for page double-buffering:
Let's say your double buffer graphics update frame rate is 3
(giving you 70/3 = 23,3 frames per second).
Your program looks like this:
...
#define UPDATE_RATE 3 /* graphics update frame rate */
...
ubyte page=0; /* initial graphics page to prepare */
...
/* prepare first graphics page */
preparepage(page);
/* start frame counting */
startvrclk(UPDATE_RATE);
/* page double-buffering main loop */
{ /* immediately after startvrclk(UPDATE_RATE) was called
* vrclk() will return UPDATE_RATE...
*/
while (vrclk()<UPDATE_RATE); resetvrclk();
/* ...which will consequently lead to the immediate display
* of the prepared first graphics page here */
displaypage(page);
/* switch graphics page to prepare */
page=1-page;
/* wait for the prepared graphics page to appear on the
* screen
*/
while (!vrclk());
/* ok, now it's time to prepare the hidden graphics page */
preparepage(page);
};
Note:
startvrclk() takes over the system timer (INT 08) and replaces
the old timer interrupt handler by its own. The old timer handler
is never being called by the startvrclk() interrupt service
routine and hence all system functions related to INT 08h are
suspended until stopvrclk() is called. Especially the system
clock is stopped once the vrclk system is active. However you
can reload the correct system time from your real time clock (if
you own an AT type PC) by calling restoretime() once you have
disabled the vrclk library services with stopvrclk().
INPUTS:
fcreset: initial value of the interrupt frame counter.
RESULT:
byte success: TRUE if the vrclk system was successfully
initialized,
FALSE if not (i.e. the vertical retrace clock is
already active).
BUGS:
This procedure suspends system functions related to INT 08h until
stopvrclk() is being called.
SEE ALSO:
stopvrclk(), restoretime()
void resetvrclk(void);
zero the interrupt frame counter and the benchmark counter
FUNCTION:
Once the frame counter has reached the desired update frame
rate it is time to start a new display cycle. This means
a) to set back the frame counter to zero - which is done by
this procedure and
b) to display new/prepared graphics.
It is most usefull to call resetvrclk() immediately after you
have waited for the frame counter to get the value of the
desired frame update rate - this will also assure that
clkload()'s benchmark timer will be resetted correctly.
See startvrclk(), clkload() for programming examples.
INPUTS:
none
RESULT:
none
BUGS:
none known
SEE ALSO:
startvrclk(), clkload()
ubyte vrclk(void);
get current value of the frame counter
FUNCTION:
This procedure returns the current value of the interrupt frame
counter. After calling startvrclk() the frame counter is
increased automagically at the start of every frame without the
user having to wait for the beginning of each frame and to
increment the frame counter manually.
INPUTS:
none
RESULT:
ubyte framecnt: current value of the frame counter
BUGS:
none known
SEE ALSO:
startvrclk()
byte stopvrclk(void);
restore old system timer interrupt handler
FUNCTION:
stopvrclk() is used to inactivate the vrclk system. It removes
the system timer interrupt handler installed by startvrclk()
and installs ye olde system timer interrupt service routine.
After stopvrclk() you may want to call restoretime() to bring
the system clock up to date.
INPUTS:
none
RESULT:
byte success: TRUE if the function was successfully executed,
FALSE if not (i.e. the vrclk system was not
active).
SEE ALSO:
startvrclk(), restoretime()
byte restoretime(void);
load the system clock with the values of the real time clock
FUNCTION:
Once the vertical retrace clock was enabled by calling
startvrclk() the system clock will stop working. The clock will
begin to work again after the vrclk system was disabled by
stopvrclk(). But the system clock will contain an incorrect time.
This procedure brings the system clock up to date by loading the
values of the AT real time clock into it. restoretime() should
be called immediately after stopvrclk(). Of couse, it only works
on an AT type PC which has a real time clock.
INPUTS:
none
RESULT:
byte success: TRUE, if the system clock was succesfully reloaded
with the values of the real time clock;
FALSE if not (battery of real time clock empty).
BUGS:
none known
SEE ALSO:
startvrclk(), stopvrclk()
uword clkload(void);
get value of the benchmark timer
FUNCTION:
The vrclk library has an integrated benchmark timer which will
be activated by startvrclk(). This benchmark timer can be used
to find out how much CPU time a certain routine requires. The
benchmark counter subdivides a frame into 64 cycles - this means
if clkload() returns 64 exactly one frame has passed. There
may be more precise ways to benchmark a procedure. But
clkload() provides a benchmark in a real world environment -
without adding any CPU overhead. In fact you can run clkload()
on the fly as demonstrated here:
...
#define UPDATE_RATE 2 /* graphics update frame rate */
...
ubyte page=0; /* initial graphics page to prepare */
uword sysload; /* variable to store benchmark timer */
...
/* prepare first graphics page */
preparepage(page);
/* start frame counting */
startvrclk(UPDATE_RATE);
/* page double-buffering main loop */
{ /* when resetvrclk() is used immediately after the desired
* update frame rate was reached, the benchmark timer will
* be resetted properly.
*/
while (vrclk()<UPDATE_RATE); resetvrclk();
/* benchmarking begins HERE */
displaypage(page);
/* switch graphics page to prepare */
page=1-page;
/* wait for the prepared graphics page to appear on the
* screen
*/
while (!vrclk());
/* ok, now it's time to prepare the hidden graphics page */
preparepage(page);
/* how long took this? How many % of CPU time are left?
* let's find out...
*/
sysload=clkload(); /* benchmarking stops HERE */
/* since our frame update rate is 2 sysload will contain
* anything from 0-128 (actually from 64-128 since we wait
* the first frame for the prepared page to appear on the
* screen)
*
* let's calc the %-tual CPU load
*/
sysload=(sysload*100)/(UPDATE_RATE<<6);
/* that's all! Wasn't that easy? And you get the CPU load
* of each double-buffer cycle in a real world environment
* without wasting valuable CPU bandwidth on benchmarking!
*/
};
INPUTS:
none
RESULT:
uword sysload: value of the internal benchmark timer. The
benchmark timer slices a frame into 64 subcycles.
Hence clkload() will return 64 when exactly one
frame has passed.
BUGS:
none known
SEE ALSO:
startvrclk(), vrclk(), resetvrclk()
APPENDIX:
=========
A) Simulating tgdlp4xx.obj's waittof() with functions of the
vrclk library:
(It is assumed that you have started the vrclk system with
startvrclk().)
resetvrclk(); while (!vrclk());
B) Simulating tgdsuppx.obj's framewait(frames) with functions of
the vrclk library:
(It is assumed that you have started the vrclk system with
startvrclk().)
resetvrclk(); while (vrclk()<frames);
Note that tgdsuppx.obj's framewait() expects a UWORD value, while
vrclkx.obj's vrclk() returns a UBYTE value. In other words:
with framewait() you can wait max. 65535 frames while with
vrclk() only 255!